package com.ls.blog.security.email;

import com.ls.blog.common.exception.CodeErrorException;
import com.ls.blog.dto.UserDetailsIml;
import com.ls.blog.service.impl.UserDetailsServiceImpl;
import com.ls.blog.utils.ObjectUtils;
import com.ls.blog.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;

import static com.ls.blog.common.consts.RedisKeyConst.EMAIL_CODE;

/**
 * @Author: crush
 * @Date: 2021-09-08 21:14
 * version 1.0
 */
@Slf4j
public class EmailCodeAuthenticationProvider implements AuthenticationProvider {

    UserDetailsServiceImpl userService;

    RedisUtil redisUtil;

    public EmailCodeAuthenticationProvider(UserDetailsServiceImpl userService, RedisUtil redisUtil) {
        this.userService = userService;
        this.redisUtil = redisUtil;
    }


    /**
     * 认证
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if (!supports(authentication.getClass())) {
            return null;
        }
        EmailCodeAuthenticationToken token = (EmailCodeAuthenticationToken) authentication;
        // 校验邮箱格式
        UserDetailsIml user = null;
        user = userService.getByEmail((String) token.getPrincipal());
        if (user==null){
            throw new CodeErrorException("用户校验错误");
        }
        String credentials = (String)token.getCredentials();
        user.setPassword(credentials);
        checkCode(user);
        EmailCodeAuthenticationToken result =
                new EmailCodeAuthenticationToken(user, user.getAuthorities());

        result.setDetails(token.getDetails());
        return result;
    }

    // 校验验证码
    public void checkCode(UserDetailsIml userDetails) throws CodeErrorException{
       String realCode = (String) redisUtil.get(EMAIL_CODE + userDetails.getEmail());
        redisUtil.del(EMAIL_CODE + userDetails.getEmail());
       if (realCode ==null || !realCode.equals(userDetails.getPassword())){
           throw new CodeErrorException("验证码错误");
       }
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return EmailCodeAuthenticationToken.class.isAssignableFrom(aClass);
    }
}
